{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from numpy import ndarray\n",
    "\n",
    "from typing import Callable, Dict, Tuple, List\n",
    "\n",
    "np.set_printoptions(precision=4)\n",
    "# GRAPHS_IMG_FILEPATH = \"/Users/seth/development/01_deep-learning-from-scratch/images/02_fundamentals/graphs/\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "%load_ext autoreload\n",
    "%autoreload 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "TEST_ALL = False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Boston data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.datasets import load_boston"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "boston = load_boston()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = boston.data\n",
    "target = boston.target\n",
    "features = boston.feature_names"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# SciKit Learn Linear Regression"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Data prep"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "s = StandardScaler()\n",
    "data = s.fit_transform(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=0.3, random_state=80718)\n",
    "\n",
    "y_train, y_test = y_train.reshape(-1, 1), y_test.reshape(-1, 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Regression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LinearRegression\n",
    "lr = LinearRegression(fit_intercept=True)\n",
    "lr.fit(X_train, y_train)\n",
    "preds = lr.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.xlabel(\"Predicted value\")\n",
    "plt.ylabel(\"Actual value\")\n",
    "plt.title(\"Predicted vs. Actual values for\\nnLinear Regression model\")\n",
    "plt.xlim([0, 51])\n",
    "plt.ylim([0, 51])\n",
    "plt.scatter(preds, y_test)\n",
    "plt.plot([0, 51], [0, 51]);\n",
    "# plt.savefig(IMG_FILEPATH + \"00_linear_real_pred_vs_actual.png\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Testing changing feature"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX4AAAElCAYAAADjk4nIAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO3de5xkZX3n8c93ehroAaVBZxUahiFKQJDLyIC4eOGigBJkAgJh0WDiyrqbrOJlFKORSzCMwfWS6MaQ6EKERRBkREiCF2bEoIAzzHAZgZVwb24DTCOXBnpmfvvHeWqorq5Tl+661/f9evWL6qpT5zx1mvnVc37neX6PIgIzM+sfs9rdADMzay0HfjOzPuPAb2bWZxz4zcz6jAO/mVmfceA3M+szDvw2LZIOkvTQDN7/LUl/2cg2lTlGSHp9zmsnSfrxNPd7hqQLZ9Y6s/Zx4O9jku6TNC7pWUmPSjpf0lZNOM4HJf178XMR8ZGI+KtGH6tWEXFRRBzW6uP6SyMz046DzYwDvx0VEVsB+wALgM+2uT1m1mQO/AZARDwKXEP2BQCApM0lfVnSA5IeS+mZoXLvl3SapP+Q9Iyk30j6w/T8G4BvAW9JVxZj6fnzJZ1d9P4PS7pb0lOSrpS0fdFrIekjkn4raUzSNyUpvfZ6ST+X9LSkJyRdUtK0d+a8b9JVSDrGRyXdk/ZzrqRK/z62kHRJ+rw3S9q7aF/bS7pc0lpJ90r6aHr+COAvgBPSubhF0sGSbit6708k/bro919IWlRpv+m1WUV/gyclXSpp2/Ta/PT5Tk5/yyckfS7vg6W/zf+W9K+pnddLeq2kr0laJ+lOSQuKtn+DpOXpHK+R9N6i196T/n94RtKopE9J2hL4V2D7tP9ni//e1gIR4Z8+/QHuA96ZHu8A3AZ8vej1rwJXAtsCrwB+BJyTXjsIeKho2+OA7ck6EycAzwHbpdc+CPx7ybHPB85Ojw8BngDeBGwO/B1wXdG2AVwFDAPzgLXAEem1i4HPpeNuAby1xvdNalPadln6rPOA/wf815zzdgYwAbwPGAQ+BdybHs8CVgJfADYDfg+4Bzi86L0XFu1rCHgBeHV6/2PAaDrfQ8A48Koa9vsx4Ib0d9wc+Afg4vTa/PT5/jHtc2/gReANOZ/v/PT32Ded02vT5/tjYAA4G1iWth0E7ib7Qtss/S2fAXZNrz8CvC093gZ4U7n/f/zT2h/3+G2ppGeAB4HHgdMBUs/4FODjEfFURDwD/DXwR+V2EhHfj4iHI2JjRFwC/BbYv8Y2nAR8JyJujogXydJNb5E0v2ibJRExFhEPkAXowpXJBLATsH1EvBARk+4lVHhfOV9Kn/UB4GvAiRW2XRkRl0XEBPAVsgB5ALAfMDcizoqIlyLiHrKAm3fexoFfA28nC7S3ANcDB6b9/TYinqxhvx8BPhcRD6VzeAbwPkmziw53ZkSMR8Qt6Th7k++KiFgZES8AVwAvRMQ/R8QG4BKytCCpjVuRneeXIuJasi/bwrmbAHaX9MqIWBcRN1c4prWIA78tiohXkPXAdiPreQLMBeYAK9Ml/Bjwb+n5KST9saTVRdu+sWhf1WwP3F/4JSKeBZ4ERoq2ebTo8fNkwQbg04CAm1Ka4U9L9p33vnIeLHp8f2pX1W0jYiPwUNp+J7IUxljRufgL4DUV9vVzsvP/9vR4OfCO9PPztE21/e4EXFH02h3AhpLj1nMuHit6PF7m98J7twceTOeg4H5e/tsdC7wHuD+l5N5S4ZjWIrOrb2L9ICJ+Lul84MvAIrJL/XFgj4gYrfReSTuR9T4PBX4VERskrSYLyJClGSp5mCxwFfa3JVl6o+JxU7sfBT6c3vdW4KeSrouIu6u9t4wdgTXp8bzUrkrbFto7iyzF8jCwHrg3InbJa3KZ534O/C/gAWAJsI7sfL4IfDNt82CV/T4I/GlEXF/6QsmVU6M9DOwoaVZR8C+kyoiIXwNHSxoE/hy4lOzcuSxwG7nHb8W+BrxL0t7pH/E/Al+V9J8AJI1IOrzM+7Yk+4e8Nm33J2Q9/oLHgB0kbZZz3IuBP5G0j6TNyVJKN0bEfdUaLOk4STukX9eldmys8JZKFkvaRtKOZDnz0hvFxfaVdExKpZxKFqRvAG4CnpH0GUlDkgYkvVHSful9jwHzS24c/xLYlSw1dlNErCH7InwzcF3aptp+vwV8MX0JI2mupKOneR7qcSPZ1cOnJQ1KOgg4CviepM2UzZfYOqXEfsfLf5vHgFdJ2roFbbQSDvy2SUSsBf6Z7AYiwGfIbtzdIOl3wE/JAlTp+35D1mP9Fdk/6D3J8tQF15L1pB+V9ESZ9/8U+EvgcrKbga8jJydexn7AjZKeJbsR/bGU/56OH5LdQF0NXA18u8q2J5B92XwAOCYiJlIO/A/I7iXcS3bl9E9AIcB9P/33SUk3A0TEc8DNwJqIeCm9/ivg/oh4PG1Tbb9fT5//x+mezQ1kXxxNldp7FPDu1Kb/DfxxRNyZNvkAcF/6/+cjZPdzSK9fDNyT0lMe1dNCivAVl5mkAHaZZorIrKu4x29m1mcc+M3M+oxTPWZmfcY9fjOzPuPA3yfS5KaD2t2OdpF0dqpR82j1rXuXXBXTcODvGxGxR0Qsb3c7YFM56Hc2cH+5dffT6/OATwK7R8RrZ3isng6c1c5lC46/XNJ/bdfx+4UDv7VMSd2YVpoHPFkYE99ObTwHTaeMY0o3aHeVOP+05ofJlTjPIJtIdCFZJcXbgN8nK472ONn0/8OK3rscOIds9ujvyCYvbVv0+nvJJmiNpW3fUHLczwC3ks1uvZhs9uY48Czw6bTd98lqyTxNNlt1j6J9nE9WuuDq1N4bgdel164jm637XNrfCSWf+53pWBvT6+en5w8gmzE7Rlaw7KCi9/wJWa2bZ8gqYP639PyWJft6lqxWzfmkSqNpu4OYXLm09BzMTu+7nGy2873ARyv87Y4EVqVz/yBwRtFr89PnP5ms5MMTZMXaCq8PpfatA34DLCanKma5c0lWUfOq1M516fEOJf9vfJFswt448Hpg57SvZ8gm/X2TyRVJy577tJ8NZNVKnwW+0e5/N7360/YG+KdFf+ipgf8F4PAUhP45BZ/PkZXZ/TBZXZjCe5eT1c15Ywp+lxf+IZN9YTwHvCu999Nks303KzruarL6LEOlbSk6xp+SlSLenKx0xOqi184nK9q2f2rvRcD3il4P4PUVPvtBTA7EI2l/7yG76n1X+n1uev1IstnDIiuU9jwVyglTW+DfdA6oUmI5p/17pvftRTY7elF6bT4VSi6T1f75BVm56R2B20vbX3KsSeeSrGbSsWQF+15B9gW9tOT/jQeAPdLfZpBs1vGX02d7K9kX1oU1nvvl5JTD9k/jfnxZ1r9+ERHXRMR6sn/Mc8lK604A3yOrJzNctP13I+L2yMoL/CVwvKQBsl7h1RHxk/TeL5MFoP9c9N6/jYgHIytBXFZEfCcinomXSwrvXVLH5YqIuCm19yIql1eu5v3Av0TEv0RWRvonwAqyYEREXB0R/xGZnwM/Bt42g+PB5HNQb+nm5RFxW2rrrWRXTe8o2Syv5PLxwBcjKzf9IPC39TQ6Ip6MiMsj4vnISnN/scyxz4+INelvs136fF9In+3fyUpJFFQ899YaDvz9q7TM7hOR1YMp/A6Ty/aWliweJCu7XFpSeWPadiTnvVOkgmNLlK0e9TuyHjJMLutcT0nhanYCjispcfxWsqCFpHdLukHZamBjZEGp1hLTeYrPQV2lmyW9WdIyZStvPU1W86a0PXnnZ3um/u1qJmmOpH+QdH/621wHDKcv/XKfbXvgqYh4Puf1iufeWqNnbzRZw+1Y9Hge2QIbT5CV5d2z8IIkpW2LSyqXzhIs/f2/AEeT5ePvIys8to6Xyzo32oNkVzAfLn0hVQe9nGy1qR9GxISkpVQuMf0cWSqkoNzIoeL3VSuxXOr/At8A3h0RL0j6GrV/ET3C1HLT9fgkWWG+N0fEo5L2IbvfUPy3Kf5sjwDbSppTFPyL/9/JPfdl9mVN4h6/1er9knaXNAc4C7gsXSFcChwp6dBUc/2TZDnmX1bY12Nkee2CV6T3PEkWQP+6zraV7q+aC4GjJB2erja2SMM0dyDLS29OdjNzvaR3A4eVHKu0nPBq4D2StpX0WrIyzZVUK7Fc6hVkvegXJO1P9kVZq0uBz6Zy0zsA/7PK9uX+NuPAmLI1fE+v9OaIuJ8sdXNGKsv8FrLqnQWVzn2541sTOPBbrb5LdhPzUbJlBj8KEBF3keVt/47sCuAo4Kh4ubxwOecAn0+X+p8iu7l8P9lVwm/ISgrX4wzggrS/46ttnHLdR5OlV9aS9UIXA7NSHvujZAFzHVmQvbLoveXKCX+XLK9+H9n9gEp1/InqJZZL/Q/grFRu+QupbbU6k+zc3pva9t0q25/B5HP5NbJ7Nk+Q/V3+rYZjngS8heyL/Gyy8/EiVD736b1fJ1sycp2kuu5HWO1cq8eqkrScbFTGP7W7LdZ9JF0C3BkRFa8WrHXc4zezhpK0n6TXSZol6QiyHv7SdrfLXuabu2bWaK8FfkA2B+Ah4L9HxKr2NsmKOdVjZtZnnOoxM+szXZHqefWrXx3z589vdzPMzLrKypUrn4iIuaXPd0Xgnz9/PitWrGh3M8zMuoqksjO1neoxM+szDvxmZn3Ggd/MrM848JuZ9RkHfjOzPtPUUT2S7iNbfm0DsD4iFqYKf5eQrRx0H3B8RKxrZjvKWbpqlHOvuYuHx8bZfniIxYfvyqIFI9Xf2KL9Ner47W6XmXWeps7cTYF/YUQ8UfTc35CVmF0i6TRgm4j4TKX9LFy4MBo5nHPpqlE++4PbGJ/YsOm5ocEBzjlmz2kFxUbvr1HHP3bfES5fOdq2dplZe0laGRELS59vR6rnaOCC9PgCYFGrG3DuNXdNCoYA4xMbOPeauzpif406/sU3PtjWdplZZ2p24A/gx5JWSjolPfeaiHgkPX6U/OXmTpG0QtKKtWvXNrRRD4+VX/o17/lW769Rx9+QczXXqnaZWWdqduB/a0S8CXg38GeS3l78YmR5prLRKSLOi4iFEbFw7twpM45nZPvhobqeb/X+GnX8AZVfubBV7TKzztTUwB8Ro+m/jwNXAPsDj0kqLGq9HfB4M9tQzuLDd2VocGDSc0ODAyw+fNeO2F+jjn/im3dsa7vMrDM1bVSPpC1JS9mlx4eRrdV6JXAysCT994fNakOewo3NRo12qba/Zo+sqXT8hTtt61E9ZjZJ00b1SPo9sl4+ZF8w/zcivijpVWRrhs4jWwv0+Ih4qtK+Gj2qpxaNCtbtHvFjZv0rb1RP03r8EXEPsHeZ558EDm3WcRuhNFiPjo3z2R/cBlB3sK404seB38zawTN3y2jk8Mx2j/gxMyvlwF9GI4N1u0f8mJmVcuAvo5HBut0jfszMSjnwl9HIYL1owQjnHLMnI8NDCBgZHvKNXTNrq65YerHVmjHc04HezDqFA38OB2sz61UO/BW4pLGZ9SIH/hyNHMtvZtZJfHM3R7tLLZuZNYsDfw5PvDKzXtX3qZ68PP72w0OMlgnynnhlZt2ur3v8hTz+6Ng4wct5/KWrRj3xysx6Vl8H/moF1Dzxysx6UV+neqrl8T2W38x6UV/3+F1Azcz6UV8Hfufxzawf9XWqp9E1eczMukFfB35wHt/M+k9fp3rMzPpR3/f4XYjNzPpNXwd+F2Izs37U16mevAlcZ/5oTZtaZGbWfH0d+PMmcK17foKlq0Zb3Bozs9bo68BfaaKWyy+bWa/q68BfaaLW6Ng4By651j1/M+s5fR34Fy0YYXhoMPf14mqdZma9oq8DP8AZ791jStmGYl51y8x6Td8HfoDNZ1c+DV51y8x6icfxF43jz+NqnWbWS/q6x19uHH8pV+s0s17T1z3+SikcgUs4mFlP6uvAn7eg+sjwENefdkgbWmRm1nx9nerxQixm1o/6usfvhVjMrB/1deAHL8RiZv2nr1M9Zmb9yIHfzKzPND3wSxqQtErSVen3nSXdKOluSZdI2qzZbTAzs5e1osf/MeCOot+/BHw1Il4PrAM+1II2mJlZ0tTAL2kH4Ejgn9LvAg4BLkubXAAsamYbzMxssmb3+L8GfBrYmH5/FTAWEevT7w8BZYfUSDpF0gpJK9auXdvkZpqZ9Y+mBX5JfwA8HhErp/P+iDgvIhZGxMK5c+c2uHVmZv2rmeP4DwTeK+k9wBbAK4GvA8OSZqde/w6AVzkxM2uhpvX4I+KzEbFDRMwH/gi4NiJOApYB70ubnQz8sFltaKSlq0Y5cMm17Hza1V6S0cy6WjvG8X8G+ISku8ly/t9uQxvqUqjbPzo2TuAlGc2su7Uk8EfE8oj4g/T4nojYPyJeHxHHRcSLrWjDTJSr2+8lGc2sW3nmbg3y6vZ7SUYz60YO/DXIW3rRSzKaWTdy4K+B6/abWS/p+7LMtXDdfjPrJQ78JZauGi0b4F2338x6hQN/kcKwzcIInsKwTcBB38x6hnP8RTxs08z6gXv8Rbph2GZeKsrMrFbu8Rfp9GGbnkFsZo3gwF+k04dtOhVlZo3gVE+RTh+22Q2pKDPrfA78JTp52Ob2w0OMlgnynZKKMrPu4FTPDLS6VHOnp6LMrDu4xz9N7Rjz3+mpKDPrDg7801TpRmszA3Enp6LMrDv0dOBv5ph332g1s27Vszn+Zo957/Qx/2ZmeXo28Dd7zLtvtJpZt+rZVE+zUzG+0Wpm3apnA38rxrz7RquZdaOeTfU4FWNmVl7P9vidijEzK69nAz90Vipm6apRzvzRGtY9PwHA8NAgZ7x3j45pn5n1j54O/K1Qy1yBpatGWXzZLUxsiE3PjY1PsPj7twBe3cvMWqtnc/ytUOtcgXOvuWtS0C+Y2BguqWxmLefAPwO1zhWoNITUM33NrNWc6ilRT5mHWucK5A0tLbxmZtZK7vEXqbfMQ61lGxYfviuDA5qy3eAseXipmbWcA3+Ress81DpXYNGCEc59395sM2dw03PDQ4Oce9zevrFrZi3nVE+Ress81DNXoJOGlppZf3PgLzKdMg8O6GbWbZzqKeIyD2bWD6oGfknH1PJcL1i0YIRzjtmTkeEhBIwMD3HOMXu6R29mPUURUycWTdpAujki3lTy3MqI2LepLSuycOHCWLFiRasOZ0kzVzAzs+ZLsXph6fO5OX5JhwNHACOSvlL00iuBjY1vonWSdiwmb2atUSnV8zhwO/ACsKbo58fAu5vfNGunZq9gZmbtk9vjj4hVwCpJF5H18OdFxN0ta5m1lReTN+tdtYzqORS4DfgJgKR9JF1R7U2StpB0k6RbJK2RdGZ6fmdJN0q6W9Ilkjab0SfoYUtXjXLgkmvZ+bSrOXDJtQ1bKL4WXkzerHfVEvjPAt4MjAFExGrg9TW870XgkIjYG9gHOELSAcCXgK9GxOuBdcCHptPwXldv+YhG89BWs95VS+CfiIixkucqDwUCIvNs+nUw/QRwCHBZev4CYFGNbe0r7c6xe2irWe+qZebuHZKOB2ZJ2hn4KHBDLTuXNACsJLtC+CbwH8BYRKxPmzwElI0kkk4BTgGYN29eLYfrKZ2QY/esZLPeVEuP/8+Bfclu8F4BvAScWsvOI2JDROwD7ADsD+xWa8Mi4ryIWBgRC+fOnVvr23qGc+xm1ixVe/wR8RzwmfQzLRExJmkZ8BZgWNLs1OvfAWjdHcsGa+YEp8WH7zppHD04x25mjVE18KcRPKU5/aeBFcA/RsRLOe+bS7o/IGkIeBfZjd1lwPuA7wEnAz+cfvPbp9kTnOqp/GlmVo9aSjb8LfBa4OL01Alko3FmAVtExMk579uL7ObtQNr20og4S9LvkQX9bYFVwPsj4sVKbejEkg0HLrm2bCXPkeEhrj/tkDa0yMxssrpLNhR5S0TsV7SjpcBNEbGfpN/kvSkibgUWlHn+HrJ8f1drxc3XelNJrq1jZrWo5ebuKyTtUPT79sAr0uOKPfVelneTdZbUkAlX9Y7jb/e4fzPrHrUE/k8Dv5L0E0k/BX4FfFrSlsBFTW1dBzt4t7lMXUUXNkQ0JPDWO46/3eP+zax7VEz1SJoFPAb8PrB7evo3EVHIZ3y5iW3rWEtXjXL5ytGqs9gKgXc66ZZ6U0mdMO7fzLpDxR5/RGwE/iEixiNiZfrp+0hSrnedZ7qBt95x/M1OPZlZ76gl1bNM0tFNb0kXqSeYT3fCVb21csptD41LPZlZ76gl8H8QuELSuKSnJK2T9FST29XR8oJ5uZz/8y+tn1awrbdWTun2A5raGuf8zQxqG8c/tRtJVo6hKS0qo9PG8ZdO3oKsN37sviNcdcsjjI1PTNp+aHCg5QXOdj7t6rL3IATcu+TIlrXDzNpn2uP4I2KDpK2B1wFbFL30ywa2r6tUmlW77M61UwL/TG7yTnds/vbDQ2UnmLnWj5nVUrLhQ8AnyKpo3gbsR1ad86CmtqzD5VWubOTompmUhXCtHzPLU0uO/1RgIXBfRLyNrFLnk01tVRdrZFXNmYzNdz19M8tTS8mGFyJiXBKSNouINZLcbczRyJ72TK8eXE/fzMrJDfxFpZMfkTQM/Ai4Jo3oeahVDew2jayq6Ty9mTVDpR7/TcCbIuK96fe/lHQosDVwddNb1sUa1dN2nt7MmqFS4J8yEDwiftbEtlgJ1+Q3s2aoFPjnSvpE3osR8ZUmtKdv5Q3bnOnVg0s1m1mpSoF/ANiK8hNSrYGatZpXs1cJM7PulDtzV9LNEfGmFrenrE6budtozVrNK2+/w0ODbLn57JZfBfjqw6y1pjNz1z39FmlWSeW894+NT2yaXVzrVcBMg3atVx/+cjBrvkoTuA5tWSv62NJVo8wqU1ANZj5ss9b3V5sU1ojVvWqZjOZVxMxaIzfwR0RfV+CcqaWrRjlwybUVa+EXAt2GMum2RgzbzCvVXE6lq4tGrO5Vy1WNVxEza41aZu5aDYpTFFsPDfLcS+uZ2JAF9Ly0Rt6CLgPSpPIK001/lBsO+vxL61n3/MSUbUuvDoqPmVe/td51CapNRvMqYgZO97WCA38DlOavS6tzQvkKnXkBbWPEpKBfz8iccv9oim8Q55WULr66KLdNOfWkomqZjOaZyuaRaK3hwN8AtS7FWBro8wJdkI3IWXz4rrnpjzOuXDMlwANV/9HUMimsls9TbyqqluN6prJVSvc58DdO1YVYOkGnD+fMW/SkVGF45tJVo5xx5ZqyVwbFhgYHal7bd2hwgC0GZ5VN4+QNCy1txzZzBjn9qD34+CWrcz+PoKmX377M729eQKixpr0Qi1WX13MvJrIe+IKzfszTz0+wsYb9jk9sYEAqe/O33LZ5XxLlUkpLV42y+Pu3MLHx5X2ve36CxZfdwhaDsxifmNrC4aFBVp9+WNl9NSpYu6Jof3O6rzVqqcdvVZQbPTM4S2wzZxDIgn4hvK6rMegXbIioeWROnnL/aM695q5JQb9gYkPw4vryLSw36tRDMK2Ryv1bcrqv8Rz4G6DcoifnHrc3q75wGCPDQzWlgfIUFlAp3nfhC6UWef9oKo2UKfN9AMBYmTSSh2BaI3kBodZwqqdByqUolq4arZoCqqQQtEv3Xeuom9JhocUqpafy0ktSduxaRiZ5CKZNl9N9zecef5MUgnO9BlI+pVJPp7RXlGdjCt7lJpItPnxXBmdNfffggDjxzTsyODD1tY0Biy+7ZVIap5FLTZpZa3hUT5PkFUgDmKWp6ZTBWeLc4/aeVk8n71jbzBnkhYmNk64MCvcbRoaHOHi3uVx1yyNTRvUsWjDCPmf+OHfUUfEoobx5AYUvrWaN0vHoH7PqPKqnxSqlOrYeGpwy7HJiY1Qcq1wp0OWNf49gSjqo8H0zOjbO5StHc68qnq4w1LT4s1Uan98t5ab9JWL9xoG/SfJy6CPDQ3XnxasFukKQOvNHazZ9oWw+e1bVeQKVJsZUugdQmsbJy8k2azJOI/frmaLWj5zjb5JKw9LqzYvXOnLmhaKx92PjEzXV1c77sql0D2Dx4btWLEJXeC3vi2MmN7wrtXk6N5Q9Ksn6kXv8TVKtREE9pQmmW9kymDyHoJzi8hDFPdzC43Ize0vbX9xLXnH/U1x0wwMVjzmQU4a6Vo2c5ONRSdaPHPibKC8FUu8i6jOpbFm4kTs6Np77JZCX3shr/4FLrs2tH/T0+ETVeQu1zESupJE1fTxT1PqRA3+b1DpWeemqUZ5/af2U52utbDkg8fDY+KZRPMvuXFt2u3py5JVW9qrFyAyDar1fnJW4MJz1I+f4O1jhxmPpCKDhocEpo3HyFl3ZELGplMLlK0c5eLe5ucerlt4o5O5n0l9vVFBdtGBk0/2Sh8fGOfeau6ZVJsIzRa0fNa3HL2lH4J+B15BlGM6LiK9L2ha4BJgP3AccHxHrmtWObpZXHnnLzWdPCUylveBZZWbfjk9s4OIbH8w9XqX0RrXZwpWqgxaM1Ngz//zS27j4xgfZEMGAsgllZy/as2J7ZjIapxtninoIqs1EM3v864FPRsTuwAHAn0naHTgN+FlE7AL8LP1uZdR747G4F5yXR6+UX6/UE69Uo1/AsfuOcPpRe0y56hDw/gPmcd+SI7n+tENqCvoX3vDApnZuiODCGx7g80snz4KutE5Br3NhPJuppvX4I+IR4JH0+BlJdwAjwNHAQWmzC4DlwGea1Y5uVu+Nx1pq+OTV4dlmzmDFoFwpDRTAsjvXbuqVl1sg5sAl19bUO827Irn4xgcn9for3WdYcNaPGXt+omN7wjPtrXuxEpupltzclTQfWADcCLwmfSkAPEqWCir3nlOAUwDmzZvX/EZ2oHI3HgW5efpqK2cNDQ7wpnlb88v/eGpSnl7AkXttV7Et1dYcKATiagXlqqVkar1SqdSeQrqpEydjNSJF5SGoNlNNv7kraSvgcuDUiPhd8WuRFQoq+y89Is6LiIURsXDu3Pwbkr1s0YIRjt13ZNJErAAuXzla9rK+0j/8AYlj9x3h5geennLCK+2zoNJNYcgCcblJXfVOkMob41/6fK03iDttMlYjJoy5MJ7NVFMDv6RBsqB/UUT8ID39mKTt0uvbAT6Spv8AABK9SURBVI83sw3dbtmda6cE6rxAUekffiFXnndFUC34LLtzbe5rQ4MDHLzb3LJ557xeed6X1Ilv3rGm5xctGKl5XYKHx8YrzjRupUb01r1Yic1U0wK/JAHfBu6IiK8UvXQlcHJ6fDLww2a1oRfUEygWH75rTWUa6j1WtdfOOWZPlt25tmxPNk/el9TZi/bk/QfM29TDH5B4/wHzpozqAcreTC5neM5gx9wMbURv3UNQbaaameM/EPgAcJuk1em5vwCWAJdK+hBwP3B8E9vQ9eq5wbtowUhNJRPyzJKmLLRSrR0jw0MsWjDCxy9ZPeW1PKJyqubsRXuWDfSlCu2stDh8XpXSdt0MbdSEsW4cgmqdo2k9/oj494hQROwVEfukn3+JiCcj4tCI2CUi3hkRTzWrDb0gb2LWcy+uL9tjPXvRnnz1hH2qLtJSzoaIST3h4vTIcy+un7I4S3HAqqfHGjTuZuuiBSMM56R8Zim7GskrMd2Om6HurVsncMmGDleu5DJkwxbzRoMU9wYrVckspzjXX9wzHRuf2LSAfLmhkuV6snlmWrKhVLm1gAEisnNx7jV3dVQ9HvfWrd1csqELLFowwpzNpn5H1zIaJK+8ciWFEgilQXxiYzBns9ncW2YyVmlPNm90TrU0z3RUy5uXu2oaHBDPvbi+Ylnpdt8INmsW9/i7xHRHg5Qrr1xNof5NPccrnZR08G5zuXzl6JQ5CCcdMK9ib3c6k5uq5c1Ly1kMzxnk2RfWbzofxWPpIb/ktHvp1iu85m6XyEvZFK9/O9N9wcvr5ealR8odL2/d3WP3HWHZnWtrDuLl9jM4S2y1xeyqM3Hr+cKodC6h/EIx0znPZu3mNXe7XCPLB+fl44eHBjnjvXvUvVjMGVeuKTtqZtmda+sKlnnppVpm4taTN5/O1VMjbwS7wJq1mwN/l2hkDfpa9lXr8ZauGs1NIdUbLGu5Cd2IYZjVhsg280aw1/i1TuDA30UaORqkln3Vsk2lm8v1BMt6bqDOdM3ealdP5a6GCsNnZ3r+XWDNOoEDv81IpV59rWmoQi+4VjNds7eWq5l6hs/WwwXWrBM48NuM5KVNqpV5Llatqmipma7ZC5WvZgpj/0sXlWlFmsmsFTyO32Ykb2Yx1J6+qbe3O90JYPWMz29Wz9wF1qwTOPDbjBQmbg0PTS6bsO75iZoLodXT251ukKx31apmlT52yQbrBA78NmOLFoyw5ebTm1kMla8aSh27b36KplKPvt46+M3smS9aMML1px1Sdga0WSs48FtDzCQ1UtoLHh4anFIQriBvwZhqPfrprF9caBNkN5QLXxQu4WDdzjd3bVpKJyENzxmccjMUak+NlFuy8ZOX3jLlRm7eDdZqwyTzbqrOktj5tKsrzmXwuHvrNe7xW93K9a6ffaFy2eZ6C58tWjDCxpzRO+V66dV69AfvNrdsmeoNERVz/o1YKtGs0zjwW93ySitsudnssjct672xWlDPDdZK2y5dNcrlK0erLk5TLqDXu3SkWTdwqsfqlhf0nh6fYPXph015frqzVeupT1Rp23rmCYyOjXPgkms3HUNQ9gvD4+6tmznwW93qnYQ005LStdQnqrRtPctCQhb8T71kNVL5oN+MNQXMWsmB3+pWb6XQmcxWrac+Ud62ecfP680X5E0QbuTSkWbt4By/1a3eSUitnK1a7iZy3vFPOmDetGYBN3rpyOnySmE2XV6IxVqiFTXo8xaEOeeYPYH8lFE96xIX9tfuHn+lz9rutlnnyFuIxYHfekatq5TVskxksQGJjRF1fWHlfdE16guwkSuyWe/yClzW82q5iVxuIZTLV45y7L4jXHXLI1MWlZlOLzpvsZUV9z816QtmdGycj1+ymhX3P8XZi/Zs+Gc1y+Mcv/WMWsb95w0tXXbnWlaffhjvP2Depnr/A1LF2kB58o5x8Y0PTnk+gItueKDu/HyzishZf3Dgt55Ry03kSj3lwkSvQpmIDRG5tYEqyTtG3joCQeWVzMpxeWebCQd+6xm1jDaq1FNuVHmGvGNUWjms3hSNyzvbTDjHbz2l2rj/SnMQ8iZ61RuU845x7L4jXHTDAw2bCdzINZitvzjwW1+pNMP33GvuatiyiJvPnrUp8G8zZ5DTj9pj07FLg38rUjStGE5r3cOB3/pOXk+53hnJ5ZQbX//CxMZNj89etCcLd9q2YUG4loCeN8oIPAO5X3kcv/WFWnu8M+0Zt3J8fa2TuLplzL+vShrP4/itb9XT451p3jzvfkCh6mcjg1qtVU+7Ycy/r0pay6N6rOe1cjGVvPsBgrrXI6im1oDeDWP+veBNaznwW89rZY+33Pj6clVAGxHUag3o3TDmvxuuSnqJA791jGZVm2xlj7fc+Pq8u2gzDWrlAvrggHjuxfWTzmE3jPnvhquSXuIcv3WEZuZ4GzFapx6l9wnybq7ONKiVDk0dnjPIsy+s31RvqPQcdlKgL9Xqv1G/c4/fOkIzc7zt7vHWm2qp58pn0YIRrj/tEO5dciRzNpvNxMbJ1xedkiev9pna/TfqN+7xW0dodo63nT3eWpaQLAxlHB0bn3RPoJ4rn07Nk9d6NVfv38jDP6evaYFf0neAPwAej4g3pue2BS4B5gP3AcdHxLpmtcG6x0yWZ+wGlYJaaWDMuxFcLah16jmsddhpPTz8c2aameo5Hzii5LnTgJ9FxC7Az9LvZl0x8qRZygXGUrX02jv1HDbjSsTDP2emaT3+iLhO0vySp48GDkqPLwCWA59pVhuse9SSDmmmdqYNagmAtS5MD2xKGQ1Ik4Jhu3rCzbgS6dS0VrdodY7/NRHxSHr8KPCavA0lnQKcAjBv3rwWNM3arV15+HanDfICY0E9vfZCezspDdKMETudmtbqFm0b1RNZkaDcQkERcV5ELIyIhXPnzm1hy6zftDttkDfpC6Y3uqXdn6dUM0bsdGpaq1u0usf/mKTtIuIRSdsBj7f4+GZTtDtt0Og0V7s/TzmNvpprd2qw27U68F8JnAwsSf/9YYuPbzZFJ6QNGhkYO+HztEKnT0rrZE1L9Ui6GPgVsKukhyR9iCzgv0vSb4F3pt/N2qoRaYNmlZuYDqdBmqeT/s4z0cxRPSfmvHRos45pNh0zTRt8fultk1bVavfNVKdBmqPdgwAayQuxmM3A0lWjfPyS1WVHKXTaQifdptNm5nbLgjbFvBCLWROce81dTau+2c86sXfdiTfNp8tF2sxmoNI/+l67mdpKnTYkFXqrdLQDv9kMVFpxyzdTp68Te9e9dNPcgd9sBvImX510wLyuu+HXSTqxd91LpaOd4zebAY+gaY5OXZilVXMHmn1j24HfbIY8kajx+vkLtRU3th34zawj9esXajPWLyjlHL+ZWQdpxY1tB34zsw7SihvbDvxmZh2kFcNGneM3M+sgrbix7cBvZtZhmn1j26keM7M+48BvZtZnHPjNzPqMA7+ZWZ9x4Dcz6zNdsQKXpLXA/e1uxzS8Gnii3Y1oA3/u/uLP3bl2ioi5pU92ReDvVpJWlFv2rNf5c/cXf+7u41SPmVmfceA3M+szDvzNdV67G9Am/tz9xZ+7yzjHb2bWZ9zjNzPrMw78ZmZ9xoG/ySQdJ2mNpI2SunLoVz0kHSHpLkl3Szqt3e1pBUnfkfS4pNvb3ZZWkbSjpGWSfpP+//5Yu9vUCpK2kHSTpFvS5z6z3W2aDgf+5rsdOAa4rt0NaTZJA8A3gXcDuwMnStq9va1qifOBI9rdiBZbD3wyInYHDgD+rE/+1i8Ch0TE3sA+wBGSDmhzm+rmwN9kEXFHRNzV7na0yP7A3RFxT0S8BHwPOLrNbWq6iLgOeKrd7WiliHgkIm5Oj58B7gB6fmX0yDybfh1MP103QsaB3xppBHiw6PeH6INg0O8kzQcWADe2tyWtIWlA0mrgceAnEdF1n9srcDWApJ8Cry3z0uci4oetbo9Zq0jaCrgcODUiftfu9rRCRGwA9pE0DFwh6Y0R0VX3dxz4GyAi3tnuNnSIUWDHot93SM9ZD5I0SBb0L4qIH7S7Pa0WEWOSlpHd3+mqwO9UjzXSr4FdJO0saTPgj4Ar29wmawJJAr4N3BERX2l3e1pF0tzU00fSEPAu4M72tqp+DvxNJukPJT0EvAW4WtI17W5Ts0TEeuDPgWvIbvZdGhFr2tuq5pN0MfArYFdJD0n6ULvb1AIHAh8ADpG0Ov28p92NaoHtgGWSbiXr6PwkIq5qc5vq5pINZmZ9xj1+M7M+48BvZtZnHPjNzPqMA7+ZWZ9x4Dcz6zMO/D1GUki6sOj32ZLWSqp7yJmk+ZL+S85r20u6bCZtnUZ79pnpkEFJf1HhteMk3ZEm5dS732FJ/2Mmbauy/80l/TQNmzyhWcdpNknLq1WplXSqpDmtalM/cuDvPc8Bb0yTSyCbYDLd2bPzgbKBPyIejoj3TXO/dZM0m6wa4kzHiucGfuBDwIcj4uBp7HcYqDvwp4qmtVgAEBH7RMQl09xH06W/00ydCjjwN5EDf2/6F+DI9PhE4OLCC5K2lbRU0q2SbpC0V3r+HUUTcVZJegWwBHhbeu7jxQdIVwO3p8cfTPv8iaT7JP25pE+k/dwgadu03XJJX0/7u13S/lXadIak70q6HvgucBZwQqHXK2l/Sb9Kx/mlpF2L2vMDSf8m6beS/iY9vwQYSu+/qOTzfAF4K/BtSeemQlznSvp1atd/S9ttJelnkm6WdJukQvXRJcDr0r7PlXRQ8VWWpG9I+mB6fJ+kL0m6GThO0utSW1dK+oWk3Ura9p+AC4H90v5fV2Yf+6Rzd6ukKyRtU3TOvyppRbqa2S+dm99KOrvc/zySTkyf7XZJXyp6/tmix++TdH56fL6kb0m6Efibkn0NSfpeOvYVwFDRa3+f2rWprr2kjwLbk02SWpa3nc1QRPinh36AZ4G9gMuALYDVwEHAVen1vwNOT48PAVanxz8CDkyPtyKr47TpfWWOMx+4PT3+IHA38ApgLvA08JH02lfJCngBLAf+MT1+e9H789p0BrASGCo6zjeK2vBKYHZ6/E7g8qLt7gG2TufgfmDHwvmpcO6WAwvT41OAz6fHmwMrgJ3TeXllev7V6XOr+Hyk1yadO+AbwAfT4/uATxe99jNgl/T4zcC1ZdpWur/SfdwKvCM9Pgv4WtFn+lJ6/DHgYbLZp5uTVU99VclxtgceSH/H2cC1wKLScwe8Dzg/PT4fuAoYKNPuTwDfSY/3IqvjXzjH26b/DqR27lX02V5dtI+y2/ln+j8u0taDIuJWZaVyTyTr/Rd7K3Bs2u5aSa+S9ErgeuArqSf8g4h4SFI9h10WWV32ZyQ9TfZFAnAb2T/4govTsa+T9EpldU/y2gRwZUSM5xxza+ACSbuQ1UQfLHrtZxHxNICk3wA7MblkdDWHAXtJKqSztgZ2IQuWfy3p7cBGsrLTr6ljvwWXpLZtBfxn4PtF53vzOvexNTAcET9Pz18AfL9ou0K9pNuANRHxSHrfPWRF9Z4s2nY/YHlErE3bXET2Jb20Slu+H1nVylJvB/4WNv1/eWvRa8dLOoXsC2Y7ssV7bp26i5q3sxo58PeuK4Evk/UUX1Vt44hYIulqshz69ZIOr/N4LxY93lj0+0Ym/39WWiOkWs2Q5yq89ldkXzh/mL7olue0ZwP1/78u4H9GxKTaSildMxfYNyImJN1HdlVRaj2TU6ml2xQ+1yxgLCL2qbN9xfuopvhvUfp3que8FP+t8j5PTSTtDHwK2C8i1qW00ZTzWOt2Vh/n+HvXd4AzI+K2kud/AZwEIOkg4ImI+J2k10XEbRHxJbLiU7sBz5ClbxrphHTstwJPp1552TaVeW9pe7bm5RvXH6zx+BPKyglXcw3w3wvbSvp9SVumYz6egv7BZFcS5dp2P7C7stE4w8Ch5Q6SPue9ko5Lx5GkvWv8LIV9PA2sk/S29NQHgJ9XeEslNwHvkPRqZTeNTyza12OS3iBpFvCHNe7vOtIAAUlv5OWrv1eSfVk8Lek1ZMt1FhSfy0rb2TS5x9+jIuIh0iV2iTOA76RL7ueBk9Pzp6ZAthFYA/xrerxB0i1k+dyvNqBpL0haRZaW+dMqbSq1DDhN2epH55DdSLxA0ueBq2s8/nnArZJujoiTKmz3T2R5+5uV5WDWAouAi4AfSbqNLO9/J0BEPCnpemU3vP81IhZLupSsTvu9wKoKxzoJ+Pv0OQbJlqy8pcbPU3Ay8C1lwyDvAf6kzvcD2ZKKkk4jO9cCro6XFxM6jSyXv5bss29Vwy7/Hvg/ku4gq9i6Mh3nlvT/wZ1kKbjri95zHvBvkh6OiIMrbGfT5Oqc1jKSlgOfiogV7W6LWT9zqsfMrM+4x29m1mfc4zcz6zMO/GZmfcaB38yszzjwm5n1GQd+M7M+8/8B2m7G3tmWeF8AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X_test[:, 12], y_test)\n",
    "plt.xlabel(\"Most important feature from our data\")\n",
    "plt.ylabel(\"Target\")\n",
    "plt.title(\"Relationship between most\\nimportant feature and target\");\n",
    "# plt.savefig(IMG_FILEPATH + \"02_most_important_feature_vs_target.png\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Non linear relationship"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Model error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "def mae(preds: ndarray, actuals: ndarray):\n",
    "    '''\n",
    "    Compute mean absolute error.\n",
    "    '''\n",
    "    return np.mean(np.abs(preds - actuals))\n",
    "\n",
    "def rmse(preds: ndarray, actuals: ndarray):\n",
    "    '''\n",
    "    Compute root mean squared error.\n",
    "    '''\n",
    "    return np.sqrt(np.mean(np.power(preds - actuals, 2)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Mean absolute error: 3.5671 \n",
      "Root mean squared error: 5.0476\n"
     ]
    }
   ],
   "source": [
    "print(\"Mean absolute error:\", round(mae(preds, y_test), 4), \"\\n\"\n",
    "      \"Root mean squared error:\", round(rmse(preds, y_test), 4))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-1.01,  0.71,  0.28,  0.71, -2.21,  2.38,  0.71, -2.66,  2.63,\n",
       "        -1.82, -2.33,  0.85, -4.19]])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "np.round(lr.coef_, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Manual linear regression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "def forward_linear_regression(X_batch: ndarray,\n",
    "                              y_batch: ndarray,\n",
    "                              weights: Dict[str, ndarray]\n",
    "                              )-> Tuple[float, Dict[str, ndarray]]:\n",
    "    '''\n",
    "    Forward pass for the step-by-step linear regression.\n",
    "    '''\n",
    "    # assert batch sizes of X and y are equal\n",
    "    assert X_batch.shape[0] == y_batch.shape[0]\n",
    "\n",
    "    # assert that matrix multiplication can work\n",
    "    assert X_batch.shape[1] == weights['W'].shape[0]\n",
    "\n",
    "    # assert that B is simply a 1x1 ndarray\n",
    "    assert weights['B'].shape[0] == weights['B'].shape[1] == 1\n",
    "\n",
    "    # compute the operations on the forward pass\n",
    "    N = np.dot(X_batch, weights['W'])\n",
    "\n",
    "    P = N + weights['B']\n",
    "\n",
    "    loss = np.mean(np.power(y_batch - P, 2))\n",
    "\n",
    "    # save the information computed on the forward pass\n",
    "    forward_info: Dict[str, ndarray] = {}\n",
    "    forward_info['X'] = X_batch\n",
    "    forward_info['N'] = N\n",
    "    forward_info['P'] = P\n",
    "    forward_info['y'] = y_batch\n",
    "\n",
    "    return loss, forward_info"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "def to_2d_np(a: ndarray, \n",
    "             type: str = \"col\") -> ndarray:\n",
    "    '''\n",
    "    Turns a 1D Tensor into 2D\n",
    "    '''\n",
    "\n",
    "    assert a.ndim == 1, \\\n",
    "    \"Input tensors must be 1 dimensional\"\n",
    "    \n",
    "    if type == \"col\":        \n",
    "        return a.reshape(-1, 1)\n",
    "    elif type == \"row\":\n",
    "        return a.reshape(1, -1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "def permute_data(X: ndarray, y: ndarray):\n",
    "    '''\n",
    "    Permute X and y, using the same permutation, along axis=0\n",
    "    '''\n",
    "    perm = np.random.permutation(X.shape[0])\n",
    "    return X[perm], y[perm]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "def loss_gradients(forward_info: Dict[str, ndarray],\n",
    "                   weights: Dict[str, ndarray]) -> Dict[str, ndarray]:\n",
    "    '''\n",
    "    Compute dLdW and dLdB for the step-by-step linear regression model.\n",
    "    '''\n",
    "    batch_size = forward_info['X'].shape[0]\n",
    "\n",
    "    dLdP = -2 * (forward_info['y'] - forward_info['P'])\n",
    "\n",
    "    dPdN = np.ones_like(forward_info['N'])\n",
    "\n",
    "    dPdB = np.ones_like(weights['B'])\n",
    "\n",
    "    dLdN = dLdP * dPdN\n",
    "\n",
    "    dNdW = np.transpose(forward_info['X'], (1, 0))\n",
    "    \n",
    "    # need to use matrix multiplication here,\n",
    "    # with dNdW on the left (see note at the end of last chapter)    \n",
    "    dLdW = np.dot(dNdW, dLdN)\n",
    "\n",
    "    # need to sum along dimension representing the batch size:\n",
    "    # see note near the end of the chapter    \n",
    "    dLdB = (dLdP * dPdB).sum(axis=0)\n",
    "\n",
    "    loss_gradients: Dict[str, ndarray] = {}\n",
    "    loss_gradients['W'] = dLdW\n",
    "    loss_gradients['B'] = dLdB\n",
    "\n",
    "    return loss_gradients"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "Batch = Tuple[ndarray, ndarray]\n",
    "\n",
    "def generate_batch(X: ndarray, \n",
    "                   y: ndarray,\n",
    "                   start: int = 0,\n",
    "                   batch_size: int = 10) -> Batch:\n",
    "    '''\n",
    "    Generate batch from X and y, given a start position\n",
    "    '''\n",
    "    assert X.ndim == y.ndim == 2, \\\n",
    "    \"X and Y must be 2 dimensional\"\n",
    "\n",
    "    if start+batch_size > X.shape[0]:\n",
    "        batch_size = X.shape[0] - start\n",
    "    \n",
    "    X_batch, y_batch = X[start:start+batch_size], y[start:start+batch_size]\n",
    "    \n",
    "    return X_batch, y_batch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "def forward_loss(X: ndarray,\n",
    "                 y: ndarray,\n",
    "                 weights: Dict[str, ndarray]) -> Tuple[Dict[str, ndarray], float]:\n",
    "    '''\n",
    "    Generate predictions and calculate loss for a step-by-step linear regression\n",
    "    (used mostly during inference).\n",
    "    '''\n",
    "    N = np.dot(X, weights['W'])\n",
    "\n",
    "    P = N + weights['B']\n",
    "\n",
    "    loss = np.mean(np.power(y - P, 2))\n",
    "\n",
    "    forward_info: Dict[str, ndarray] = {}\n",
    "    forward_info['X'] = X\n",
    "    forward_info['N'] = N\n",
    "    forward_info['P'] = P\n",
    "    forward_info['y'] = y\n",
    "\n",
    "    return forward_info, loss"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "def init_weights(n_in: int) -> Dict[str, ndarray]:\n",
    "    '''\n",
    "    Initialize weights on first forward pass of model.\n",
    "    '''\n",
    "    \n",
    "    weights: Dict[str, ndarray] = {}\n",
    "    W = np.random.randn(n_in, 1)\n",
    "    B = np.random.randn(1, 1)\n",
    "    \n",
    "    weights['W'] = W\n",
    "    weights['B'] = B\n",
    "\n",
    "    return weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "def train(X: ndarray, \n",
    "          y: ndarray, \n",
    "          n_iter: int = 1000,\n",
    "          learning_rate: float = 0.01,\n",
    "          batch_size: int = 100,\n",
    "          return_losses: bool = False, \n",
    "          return_weights: bool = False, \n",
    "          seed: int = 1) -> None:\n",
    "    '''\n",
    "    Train model for a certain number of epochs.\n",
    "    '''\n",
    "    if seed:\n",
    "        np.random.seed(seed)\n",
    "    start = 0\n",
    "\n",
    "    # Initialize weights\n",
    "    weights = init_weights(X.shape[1])\n",
    "\n",
    "    # Permute data\n",
    "    X, y = permute_data(X, y)\n",
    "    \n",
    "    if return_losses:\n",
    "        losses = []\n",
    "\n",
    "    for i in range(n_iter):\n",
    "\n",
    "        # Generate batch\n",
    "        if start >= X.shape[0]:\n",
    "            X, y = permute_data(X, y)\n",
    "            start = 0\n",
    "        \n",
    "        X_batch, y_batch = generate_batch(X, y, start, batch_size)\n",
    "        start += batch_size\n",
    "    \n",
    "        # Train net using generated batch\n",
    "        forward_info, loss = forward_loss(X_batch, y_batch, weights)\n",
    "\n",
    "        if return_losses:\n",
    "            losses.append(loss)\n",
    "\n",
    "        loss_grads = loss_gradients(forward_info, weights)\n",
    "        for key in weights.keys():\n",
    "            weights[key] -= learning_rate * loss_grads[key]\n",
    "\n",
    "    if return_weights:\n",
    "        return losses, weights\n",
    "    \n",
    "    return None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_info = train(X_train, y_train,\n",
    "                   n_iter = 1000,\n",
    "                   learning_rate = 0.001,\n",
    "                   batch_size=23, \n",
    "                   return_losses=True, \n",
    "                   return_weights=True, \n",
    "                   seed=180708)\n",
    "losses = train_info[0]\n",
    "weights = train_info[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(list(range(1000)), losses);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "def predict(X: ndarray,\n",
    "            weights: Dict[str, ndarray]):\n",
    "    '''\n",
    "    Generate predictions from the step-by-step linear regression model.\n",
    "    '''\n",
    "\n",
    "    N = np.dot(X, weights['W'])\n",
    "\n",
    "    return N + weights['B']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "preds = predict(X_test, weights)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Mean absolute error: 3.5644 \n",
      "Root mean squared error: 5.0497\n"
     ]
    }
   ],
   "source": [
    "print(\"Mean absolute error:\", round(mae(preds, y_test), 4), \"\\n\"\n",
    "      \"Root mean squared error:\", round(rmse(preds, y_test), 4))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "22.0776"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.round(y_test.mean(), 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.2287"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.round(rmse(preds, y_test) / y_test.mean(), 4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "RMSE is 23% on average of y."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.xlabel(\"Predicted value\")\n",
    "plt.ylabel(\"Actual value\")\n",
    "plt.title(\"Predicted vs. Actual values for\\ncustom linear regression model\");\n",
    "plt.xlim([0, 51])\n",
    "plt.ylim([0, 51])\n",
    "plt.scatter(preds, y_test)\n",
    "plt.plot([0, 51], [0, 51]);\n",
    "# plt.savefig(GRAPHS_IMG_FILEPATH + \"01_linear_custom_pred_vs_actual.png\");"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "NUM = 40\n",
    "a = np.repeat(X_test[:,:-1].mean(axis=0, keepdims=True), NUM, axis=0)\n",
    "b = np.linspace(-1.5, 3.5, NUM).reshape(NUM, 1)\n",
    "\n",
    "test_feature = np.concatenate([a, b], axis=1)\n",
    "test_preds = predict(test_feature, weights)[:, 0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X_test[:, 12], y_test)\n",
    "plt.plot(np.array(test_feature[:, -1]), test_preds, linewidth=2, c='orange')\n",
    "plt.ylim([6, 51])\n",
    "plt.xlabel(\"Most important feature (normalized)\")\n",
    "plt.ylabel(\"Target/Predictions\")\n",
    "plt.title(\"Most important feature vs. target and predictions,\\n custom linear regression\");\n",
    "# plt.savefig(GRAPHS_IMG_FILEPATH + \"03_most_important_feature_vs_predictions.png\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Coefficients"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-1.0954,  0.7353,  0.1977,  0.7475, -2.2849,  2.2006,  0.7195,\n",
       "       -2.6384,  2.5358, -1.6892, -2.3162,  0.8435, -4.2553])"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.round(weights['W'].reshape(-1), 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-1.0148,  0.7065,  0.276 ,  0.7092, -2.206 ,  2.3793,  0.7133,\n",
       "        -2.6625,  2.6325, -1.8172, -2.3266,  0.8465, -4.1889]])"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.round(lr.coef_, 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[22.6312]])"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.round(weights['B'], 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([22.6195])"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.round(lr.intercept_, 4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Coefficients are the same in the SciKit Learn linear regression as in the \"custom\" linear regression."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Theoretical relationship between most important feature and target"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [],
   "source": [
    "NUM = 40\n",
    "a = np.repeat(X_test[:,:-1].mean(axis=0, keepdims=True), NUM, axis=0)\n",
    "b = np.linspace(-1.5, 3.5, NUM).reshape(NUM, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_feature = np.concatenate([a, b], axis=1)\n",
    "preds = predict(test_feature, weights)[:, 0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(6, 51)"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(np.array(test_feature[:, -1]), np.array(preds))\n",
    "plt.ylim([6, 51])\n",
    "# plt.savefig(GRAPHS_IMG_FILEPATH + \"/04_relationship_most_impt_feat_preds.png\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Neural network regression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "def sigmoid(x: ndarray) -> ndarray:\n",
    "    return 1 / (1 + np.exp(-1.0 * x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYYAAAEWCAYAAABi5jCmAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO3deXxU9bnH8c9DQhIgYU9AIAIKqMiiGMFd6671qq1L1ep1xbbW1lqvrVXrtVatW+2qttZaxN26UnetWleQiOyC7EvY1yxkIclz/zgH7yQmkIFkTmbyfb9e88qc/TlnJueZ3+93zu+YuyMiIrJNu6gDEBGR1kWJQURE6lBiEBGROpQYRESkDiUGERGpQ4lBRETqUGKIkJl918zebG3bNbP3zOyyRqaZmf3DzDaa2actF2WD237NzC5M5DbD7bqZDUr0dsNtH2Vmy7cz/VAzm2dmpWZ2eiJjk9SlxNDCzOwwM/vYzDab2QYz+8jMDgRw98fd/fhEx7SL2z0MOA7o5+6jmzGsOszsZjN7LHacu5/k7o+01DZ3lZldZGYf1hs3zsxubcHN3gL82d2z3f3FFtxOwoTJsDZMdttejf4giDJxx8Sw2MzKY+JN+A++5pQedQCpzMw6Ay8DPwCeATKAw4HKKOPaRf2Bxe5eFnUgAgSfx6yGJpiZAebutYkNqVmscPd+UQcRp/9y97ejDqJZuLteLfQCCoBN25l+EfBhzPDxwFxgM3A/8B/gsph5PwJ+B2wCFgKHhOOXAWuAC2PW1QUYD6wFlgA3Au0a2e5xwJxwu3+O3W69eC8FKoAaoBT4Vf11hfM5MCh8Pw64D3gFKAEmAXvGzLsv8BawAVgNXA+cCFQBW8PtTAvnfS/meLQL92lJuO/jgS7htAFhDBcCS4F1wA3b+RzGAX8J4ygJ979/I/vT4HEF9ql3bDYBl4f7UBWO+1e4jj7Ac+E6FgE/jtlWhzCejcBs4FpgeSNxLwBqgfJw/ZnhMbqN4LtSDgwKtzchPMbzgbEx67gZ+CfwWLjvM4AhwC/C47oMOL6R7e8ZrnNUzH6tBY7axf+boxrb5wbmfT/8fMrCY/CdcPzYcF83hPvep5HlvxN+Bp3D4ZOAVUBunDEvBo6N+pzTXK/IA0jlF9AZWA88En7hutWbfhHhSRXoCRQD3yYoyV0VnlRiE0M1cDGQBtxKcNK7LzwhHB/+Y2eH848HXgJyCE6UXwKXNrLdEuBMoD1wdbidryWG+ss2NByOq58Y1gOjw/16HHgqnJYDrASuAbLC4THhtJuBx+qt972Y43FJ+I+/B5ANPA88Gk4bEMbwN4IT7UiCUto+jezTuPAYHBEeyz/U28fY/WnSca237ltjhtsBnwE3EZQg9yBI8ieE0+8APgC6A/nATLZzkqTeCSk8RksJEm56+Jm+T/BDIwvYj+DkfXTMca4ATgjnH09worwhXHYssGg72x9LkMA6Am8A98RMu58gQTb0mr6ddR5FkExXh7H8Dui0nfm/+nzC4aMJfgyMCj/PPwHvb2f5x8PPqQewAjglZtr07ezD/fU+h9XhsX0TGBn1+WdXXpEHkOovgl+S44DlBCfcCUCvcNpXJxLgv4FPYpYzgl9rsYlhXsz04eE/RK+YcevDf/y08B9raMy07wHvNbLdifW2u5zmTQwPxUw7GZgTvj8X+LyR7dzM9hPDv4ErYqbtRZBI0/n/xNAvZvqnwDmNbGscYbIKh7MJfvnnx+5PPMe13rpjE8MYYGm9eX4B/CN8vxA4MWba5cSfGG6JGc4P9yUnZtxvgHExx/mtmGn/RfDLOy0czgn3v+t2YphAUNKYDmQ2w/9Mb2AoQRIdSJDY/rqd+esnhr8Dd9X7PLcCAxpZvitBMp2xve3sIOZDCX6EdAw/z1XbO2at/aXG5xbm7l+4+0Ue1JcOIyhu/76BWfsQJIJtyznBCTrW6pj35eF89cdlE5QC2hNUdWyzBOjbxO0ua2C+XbEq5v2WMEYITloLdnKdffj6/qUDvZqw3YbEHoNSgiqIPvXmiee4NqY/0MfMNm17EVSfbYu7zudRb1tNFbt8H2CDu5dsJ+b636F17l4TMwzbP3Z/I/hu/8nd42o/M7PDYxpsZwG4+yp3n+3ute6+CPgZcEYcq63z3Qg/z/U08jm5+yaC6rRhwG/jiT9mHR+5e7m7b3H33xCUKA7fmXW1BkoMCeTucwh+QQ5rYPJK4KvGtrDhcGcb39YR/ELqHzNud6Coke3m19tufgPzNaaM4FfStuV7x7HsMoKqlIb4DpZdwdf3r5q6J7l4xB6DbIKqnBX15tnRcW0o5vrjlhFUzXSNeeW4+8nh9DqfR7j+eMVucwXQ3cxyGol5l4TH6vcEv9JvNrPuMdP+Uu/KotIGksAHHlxRle3u+25nf+I5V9X5bphZJ4Jqogb32cz2I6iafBL4Y71ps7azD3/ZTgxOUPpOSkoMLcjM9jaza8ysXzicT1B9MrGB2V8BhpvZ6WaWDvyQoEgdt/DX3jPAbWaWY2b9gZ8SNDA2tN19zezb4XZ/HOd2p4XL72dmWQRVE031MrCbmf3EzDLDWMeE01YDA8ysse/ok8DVZjYwPDndDjzt7tVxbD/WyeGlxRnArwmq1+qUnJpwXFcD/cJ1EDMuNvl9CpSY2c/NrIOZpZnZsG2XMIfr/4WZdQu/Nz/ayf3ZFvMy4GPgN2aWZWYjCC4iaOi7sDP+ABS6+2UE36WvTpbu/v2Yk379V2NJADP7hpn1D++ZySdod3lpOzHUP8ZPAheH38lMgu/GJHdf3MC2sgiOxfUE7Xd9zeyKmH3Ydzv78P1wHbuH95NkhMf4WoLS5UfbP3StlxJDyyohqFOeZGZlBAlhJkFjax3uvg44C7iLoNg7FChk5y9t/RHBr/mFwIfAE8DD29nuHeF2BxPHF9rdvyS4lv5tYF64raYuW0JwRdR/EVT7zAO+EU7+Z/h3vZlNaWDxh4FHCeqfFxE0oO7KSfQJ4H8JqpAOAM5vZL7tHdd3CC4dXWVm68JxfweGhtVGL4bJ5RSCtqBFBKWQhwiudoLgSq8l4bQ3w33cVecStLusAF4A/teb4bJKMzuN4AqyH4SjfgqMMrPv7uKq9ydIZmXh3xkEP1gaczPwSHiMzw737ZcEV36tJLh66pxGlv0NsMzdHwirwc4HbjWzwXHEmwM8QHAlWRHBMTnJ3dfHsY5WxcKGE2llwl/Ky4Hvuvu7UceTysxsHEED741RxyLSGqjE0IqY2Qlm1jUs/l5PUEfZULWTiEiLUWJoXQ4muEpnHUH1yunuXr79RUREmpeqkkREpA6VGEREpI6k70SvZ8+ePmDAgKjDEBFJKp999tk6d89taFrSJ4YBAwZQWFgYdRgiIknFzBq9q15VSSIiUocSg4iI1KHEICIidSgxiIhIHQlLDGb2sJmtMbOZjUw3M/ujmc03s+lmNipRsYmIyP9LZIlhHEHnUo05iaADt8EEDyd5IAExiYhIPQlLDO7+PkHPlY05DRjvgYlAVzPbLTHRiYjINq3pPoa+1H3y1PJw3Mr6M5rZ5QSlCnbffWeeYyIi0npVVddSXLGVzeVbKa2opqyymrKqGsoqqymtrGZLVTWllTUcu08eI/p1bfbtt6bE0GTu/iDwIEBBQYE6exKRVsndKamsZn1pFetKK1lfWsna0irWl1ayactWisuDk/+2JLC5fCvF5dWUb63Z8cqBvJzMlE8MRdR9pGE/munxgyIiza2qupbVxRWs2FTOys0VrNhczspNFazcXM6akkrWlVSyrqyKquraBpfPyUqnS4f2dM5qT5cO7RnYs1Od4c4dgr85Wel0zEgnOzOdjplpZGem0ykznY7t02jXrmWeHtqaEsME4Eoze4rgqWeb3f1r1UgiIolSWlnNkvVlLF63hcXry1i8rozF68tYsn4La0srqd85deesdPp07UCvzlkMzsuhZ3YGPbMz6RHzNzc7k26dMmif1nrvFkhYYjCzJ4GjgJ5mtpzgMYrtAdz9L8CrwMnAfGALwfNXRURaXHlVDfPWlDBnZQlzVpUwd3UxX64uZW1J3Sfr5uZkMrBHJ44ckkufrh3o0zWL3br8/99Oma3pt/bOS9heuPu5O5juwA8TFI6ItFHlVTXMXLGZqUs3MXX5JmavKGbx+rKvfv1nprdjSK8cjhicyx65nRjQoxMDenZkQI9OKXPi35G2sZci0mat2lzBJwvXMXnxRqYu3cTc1SXU1AZZoG/XDgzv24VTR/Zh79457NU7h/49OpHWQnX3yUKJQURSypriCj5ZuJ6JC9fzyYL1LF6/BQgae/fL78oP9t6T/fK7MjK/K7k5mRFH2zopMYhIUqutdWYUbebfc9bw7pw1zCjaDASJYMzAHpx/UH8O3rMH+/Tu3GJX8aQaJQYRSTpba2r5eMF6Xp2+kn/PWcO60kraGYzavRvXnrAXRw7JZZ/dOrf5KqGdpcQgIkmhptaZvHgD/5q2gtdmrmJDWRU5mekctXcex+ydx5FDcunWKSPqMFOCEoOItGrLNmzh6cnLePaz5awqrqBD+zSOHdqL/xqxG0fulUtmelrUIaYcJQYRaXWqqmt5c/Yqnp68jA/mraOdwZFDcrnxlH04eu88Ombo1NWSdHRFpNXYWFbFE58u5ZGPF7OmpJK+XTtw9bFDOKugH326dog6vDZDiUFEIrdoXRl//3Ahz362nIqttRw+uCd3njmCIwbnqgE5AkoMIhKZhWtL+dM783lpahHp7dpx+v59uPSwPdird07UobVpSgwiknCL1pXxp3/P48WpRWSkt+PSwwYy9og9yMvJijo0QYlBRBJofWklv397Hk98upT2acalhw3k8iP21B3IrYwSg4i0uMrqGsZ9tJg/vzOfLVtrOG/07vz4mMFKCK2UEoOItKi3Z6/mVy/PYtmGcr6xVy43fHMfBuWpDaE1U2IQkRaxanMFN0+YxeuzVjE4L5vxl4zmiCG5UYclTaDEICLNqrbWeWzSEu56fS5ba2q59oS9GHv4HmSkt94nlkldSgwi0myWb9zCNc9MY9KiDRw+uCe/Pm0YA3p2ijosiZMSg4jsMnfn2c+W86t/zQbgrjNHcNYB/TDTzWnJSIlBRHbJxrIqrnt+Om/MWs3ogd357Vkjye/eMeqwZBcoMYjITvt86UaufOJz1pZUcv3Je3PpYXuoC4sUoMQgInFzd8Z/soRbX5lNr85ZPPuDgxnRr2vUYUkzUWIQkbiUVVbz8+em8/L0lRyzdx73nr0fXTq2jzosaUZKDCLSZEWbyrnskULmrirm5yfuzfeO2EPPUU5BSgwi0iRTlm7k8vGfUbm1hn9cPJojdbNaylJiEJEdemlqEdc+O53enbN4cuwYBvdSlxapTIlBRBrl7jzwnwXc9fpcRg/szl/OP4DunTKiDktamBKDiDSotta5/dUveOjDRZw6sg/3nDVS3Vq0EUoMIvI1W2tq+flz03l+ShEXHTKAm04ZqkbmNkSJQUTqqNhawxWPT+GdOWv46XFD+NHRg9S1RRujxCAiX6nYWsPY8YV8OH8dvz59GBcc1D/qkCQCSgwiAtRNCnedMYKzCvKjDkkiktCWJDM70czmmtl8M7uugem7m9m7Zva5mU03s5MTGZ9IW1VeVcNljwRJ4e4zRyoptHEJSwxmlgbcB5wEDAXONbOh9Wa7EXjG3fcHzgHuT1R8Im3VtpLCRwuCpHDmAf2iDkkilsgSw2hgvrsvdPcq4CngtHrzONA5fN8FWJHA+ETanK01tVz5xBQ+WrCOe5QUJJTIxNAXWBYzvDwcF+tm4HwzWw68CvyooRWZ2eVmVmhmhWvXrm2JWEVSXm2t8/Nnp/P2F2u45bRhnKGkIKHWdrfKucA4d+8HnAw8amZfi9HdH3T3AncvyM1Vfy0i8XJ3bnl5Ns9/XsQ1xw3R1UdSRyITQxEQ26LVLxwX61LgGQB3/wTIAnomJDqRNuSP/57PuI8Xc+lhA7ny6EFRhyOtTCITw2RgsJkNNLMMgsblCfXmWQocA2Bm+xAkBtUViTSjpz5dyu/e/pIzRvXjhpP30c1r8jUJSwzuXg1cCbwBfEFw9dEsM7vFzE4NZ7sGGGtm04AngYvc3RMVo0iq+2DeWm54cSZHDMnlzjOGq5sLaVBCb3Bz91cJGpVjx90U8342cGgiYxJpK+auKuGKx6YwOC+b+87bn/S01tbEKK2FvhkibcCa4gouGTeZDhlpPHzRgeRk6VGc0jh1iSGS4sqrarhsfCEbyqr45/cPpk/XDlGHJK2cEoNICnN3fvH8dGYUbebBCwoY1rdL1CFJElBVkkgK+/uHi3hx6gquOW4Ixw3tFXU4kiSUGERS1Ifz1nH7q19w0rDe/PAbuldBmk6JQSQFLV2/hSufnMKgvGzuOWuk7lWQuCgxiKSYLVXVXP5oIbW1zoMXFNApU02JEh99Y0RSiLtzwwszmbu6hH9cdCADenaKOiRJQioxiKSQfxYu54XPi7jqmMEctVde1OFIklJiEEkRc1YV88uXZnLooB786OjBUYcjSUyJQSQFlFVW88PHp9C5Q3t+/539SVMfSLILlBhEkpy7c+OLM1m0row/nLMfuTmZUYckSU6JQSTJPVO4jBc+L+Inxw7hkD31+BLZdUoMIkls/ppS/nfCLA4b1FM3sUmzUWIQSVJV1bX85OnP6ZiRzr1nj1S7gjQb3ccgkqR+9/aXzCwq5q8XHEBe56yow5EUohKDSBKauHA9f/nPAs45MJ8T9u0ddTiSYpQYRJLM5vKtXPPMNPp378gvTxkadTiSglSVJJJkbnppJquKK3juB4eoHyRpESoxiCSRl6YW8dLUFVx1zGD2y+8adTiSopQYRJLE6uIKfvniTEbt3pUrjtoz6nAkhSkxiCSB4BGdM6iqqeW3Z+9Hepr+daXl6NslkgSen1LEO3PWcO0JezNQXWlLC1NiEGnlVhdX8Kt/zeLAAd24+JABUYcjbYASg0grFluFdNeZI2mnu5slAZQYRFoxVSFJFJQYRFopVSFJVJQYRFohVSFJlJQYRFqhl6auUBWSRCbuxGBmncwsrSWCERHYvGUrt74ym5H5XblIVUgSgR0mBjNrZ2bnmdkrZrYGmAOsNLPZZna3menpICLN6K435rChrIrbTh+mZyxIJJpSYngX2BP4BdDb3fPdPQ84DJgI3Glm5zdlY2Z2opnNNbP5ZnZdI/OcHSadWWb2RBP3QyQlTFm6kSc+XcrFhw5kWN8uUYcjbVRTumY81t231h/p7huA54DnzKz9jlYSVj/dBxwHLAcmm9kEd58dM89gggR0qLtvNLO8Ju6HSNKrrqnl+udn0Csni6uPGxJ1ONKG7bDEsC0pmNkfzKzBcm1DiaMBo4H57r7Q3auAp4DT6s0zFrjP3TeG613ThPWKpIRxHy9mzqoSbj51KNnqTlsiFE/jcwkwwcw6AZjZCWb2URzL9wWWxQwvD8fFGgIMMbOPzGyimZ3Y0IrM7HIzKzSzwrVr18YRgkjrVLSpnHvf+pJj9s7TE9kkck3+WeLuN5rZecB7ZlYFlAINthPsYjyDgaOAfsD7Zjbc3TfVi+VB4EGAgoICb+YYRBLuVxNmUevOzafuSyMFc5GEaXKJwcyOIajqKQN6Aj929w/i2FYRkB8z3C8cF2s5MMHdt7r7IuBLgkQhkrLemr2aN2ev5qpjhpDfvWPU4YjEVZV0A/BLdz8KOBN42syOjmP5ycBgMxtoZhnAOcCEevO8SFBawMx6ElQtLYxjGyJJZUtVNTdPmMWQXtlcdvjAqMMRAeKrSjo65v0MMzuJ4KqkQ5q4fLWZXQm8AaQBD7v7LDO7BSh09wnhtOPNbDZQA1zr7uubvjsiyeUPb8+jaFM5//z+wbTXw3ekldhhYjAzc/ev1eO7+8qweqnReRpY5lXg1Xrjbop578BPw5dISpuzqpiHPlzEdwryOXBA96jDEflKk25wM7MfmdnusSPD6qCDzewR4MIWiU4kRdXWOtc/P4MuHdpz3Ul7Rx2OSB1NqUo6EbgEeNLMBgKbgCyC6qA3gd+7++ctF6JI6nm6cBlTlm7inrNG0q1TRtThiNSxw8Tg7hXA/cD94R3OPYHy+peQikjTrCut5I7X5jBmYHfOGFX/Vh6R6DWlE72TzawPBHc4u/tKJQWRnXf7K1+wpaqa2741TPcsSKvUlKqkbwG3mFkvgp5VpwFTw7+z3b2mBeMTSSkfL1jH858XceU3BjEoLyfqcEQa1JS+ksa6ewHwAMENZwuBbwCTgCUtG55I6qisruHGF2eye/eOXHm0equX1iuenrq+4+4jtw2Y2f3Atc0fkkhq+ut/FrJwbRnjLj6QrPZ61pW0XvHcUVNsZgdsG3D3zwjuTBaRHVi8row/vzufb47YjaP2Um/y0rrFU2K4BHjBzCYDnwHDgaZ0ty3Sprk7v3xpJplp7bjplKFRhyOyQ025Kunm8G0eQfcXr4XvZwMnt1hkIiniX9NX8sG8dfzPCXvRq3NW1OGI7FBTSgxvhH+vAvYFMgmSwjTgaOCfLROaSPLbXL6VX788m+F9u3D+Qf2jDkekSZpyg9sn4d+zAcwskyBBDAfGoMQg0qjfvjmX9aWVPHzhgaS10z0Lkhya3MZgZt2Bq/n/aqTx7v5ISwUmkuymLtvEoxOXcOHBAxjer0vU4Yg0WTxXJT1F8HjPfwEdgQ/NbHSLRCWS5KprarnhhRnkZmdyzfG6eE+SSzxXJeW6+13h+5fN7GngCeCg5g9LJLmN/2QJs1YUc995o8jJah91OCJxiafEsMHMhm8bcPeFBCUHEYmxcnM5v31zLkftlcvJw3tHHY5I3OIpMfwQeNbMPgBmAEOBBS0SlUgSu+Vfs6mudW45VZ3kSXJqconB3ecAo4B3CRqgpwHntlBcIknpnTmreW3mKn58zGB276ECtSSneEoMEDx985kWiUQkyZVX1XDTS7MYlJfN2MP3iDockZ0Wz+WqDwHfNLNqYAUwHZju7n9qqeBEkskf35nH8o3lPH35QWSkx9N8J9K6xFNiOBzo5+41ZtYXGAmMaJmwRJLLl6tL+Nv7CznzgH6M2aNH1OGI7JJ4EsMkoAewxt2LgCLg1RaJSiSJ1NY6N7wwg+ysdK4/eZ+owxHZZfGUd/8K/MfM/sfMDjcz3copAjz72XImL97I9SftQ/dOGVGHI7LL4kkMjwHjCUoZVwAfm5kuV5U2bUNZFbe/9gUHDujGmQf0izockWYRT1XScnf/TeyIsEM9kTbr9le/oLSimtu+NZx26iRPUkQ8JYapZnZV7Ah3r2zmeESSxicL1vPsZ8sZe8QeDOmVE3U4Is0mnhJDL+BYM/s5MIXgBrep7q5ut6XNqayu4YYXZ5DfvQM/Pnpw1OGINKsmJ4ZGnscwGj2PQdqgB95bwMK1ZTxyyWg6ZKRFHY5Is4r3zudt1UdTwpdIm7NgbSn3v7uAU0f24cghuVGHI9Ls4rnzeR5B53nTgKnANHdf3EJxibRK7sE9C1nt23HjKbpnQVJTvPcxrALWAycBM81shpndYmbqcF7ahOemFDFx4QauO2kf8nKyog5HpEXEkxjOd/cr3P3P7v594DCCnlaLgXubsgIzO9HM5prZfDO7bjvznWFmbmYFccQn0qI2lFVx2yuzOaB/N845MD/qcERaTDyJYbOZfdU3krtPBY5093uAQ3e0sJmlAfcRlDaGAuea2dAG5ssBriLogkOk1bjtlS8oqajmdt2zICkunsbn7wGPm9lUgjaGvYAt4bSm9AMwGpgfPvkNM3sKOA2YXW++XwN3AtfGEZtIi/p4wTqem7KcK47ak716654FSW07LDGY2c3h2x7AN4DXgVxgHkE33J2Ap5qwrb7Aspjh5eG42G2NAvLd/ZUdxHS5mRWaWeHatWubsGmRnVextYYbX5jJ7t078iPdsyBtQFOqkt4I/14FfAL8BtgP6Akc4+5l7n7rrgZiZu0I2iqu2dG87v6guxe4e0Furi4XlJZ1/7vzWbiujFtPH6Z7FqRN2GFVkrt/Ev5t6Aa3MTT9BrciILbFrl84bpscYBjwXvic3N7ABDM71d0Lm7gNkWb1xcpi7n9vAd/avy9H6J4FaSOa3PhsZu+bWefwBrfRQDfg+ji2NRkYbGYDzSwDOAeYsG2iu292957uPsDdBwATASUFiUx1TS0/e3Y6XTu256ZTvnadhEjKiueqpC7uXmxmBwBjCRLD35q6sLtXA1cSVE19ATzj7rPC+yBOjSdokUT42weLmFG0mV+dOoxues6CtCHxXJW01czSgf8G7nT3Z8wsrl/z7v4q9Z765u43NTLvUfGsW6Q5LVhbyu/e/pIT9u3FycN7Rx2OSELFkxj+SNAdRhaw7ea07GaPSCRitbXOdc9NJyu9Hb8+bRhhm5dImxFP76rjzex5oMbdy81sEMFVSiIp5dGJS5i8eCN3nzmCvM7q9kLanrh6V3X30pj384GLmz0ikQgt27CFO1+fwxFDcvWoTmmz4ml8Fklp7s71L8zAgNu/pSokabuUGERCT3y6lA/mrePnJ+1Nv24dow5HJDJKDCLAkvVl3PbKFxw2qCfnj+kfdTgikVJikDavpta55plppLUz7jpzhHpOlTYv7kd7iqSav32wkMIlG7n37JH06doh6nBEIqcSg7Rpc1YVc++bX3Livr351v59d7yASBugxCBtVlV1LVc/PY3OHdK5TVchiXxFVUnSZv3x3/P4YmUxD15wAD2yM6MOR6TVUIlB2qSJC9dz/3vzOfOAfhy/r/pCEomlxCBtzsayKq5+eiq7d+/IzafuG3U4Iq2OqpKkTXF3fv7cdNaVVvL8Dw4lO1P/AiL1qcQgbcpjk5by5uzV/OyEvRner0vU4Yi0SkoM0mbMWVXMr1+ezRFDcrn0sIFRhyPSaikxSJtQXlXDj5/8nM5Z6fz2rJG6u1lkO1TBKm3CzRNm8eXqUh65ZDS5Obo0VWR7VGKQlPfM5GU8XbiMK47akyOH5EYdjkirp8QgKW1m0WZ++dJMDh3Ug2uO3yvqcESSghKDpKzNW7ZyxeNT6NYxgz+csz9palcQaRK1MUhKqq11rvnnVFZsKufp7zeWmUoAAAycSURBVB1MT3V5IdJkKjFISnrgPwt4+4s13PjNfTigf7eowxFJKkoMknLemr2ae96cy6kj+3DhIQOiDkck6SgxSEqZs6qYnzz1OcP7duGuM0eoK22RnaDEICljfWkllz1SSKfMdB68oICs9mlRhySSlNT4LCmhqrqWHzw+hTUllTzzvYPp3SUr6pBEkpZKDJL03J1fvjiTTxdt4O4zR7BffteoQxJJakoMkvT+9M58ni5cxo+OHsRp++m5zSK7SolBktozhcu4960v+faovvz0uCFRhyOSEpQYJGm9N3cNv3h+BocP7skd39YVSCLNJaGJwcxONLO5ZjbfzK5rYPpPzWy2mU03s3+bWf9ExifJY8byzVzx+BT26pXDA+cfQEa6fuOINJeE/TeZWRpwH3ASMBQ418yG1pvtc6DA3UcAzwJ3JSo+SR7zVpdw4T8+pVvHDMZdfKAezynSzBL5M2s0MN/dF7p7FfAUcFrsDO7+rrtvCQcnAv0SGJ8kgcXryvjuQ5NIa2c8ftkY8jrrslSR5pbIxNAXWBYzvDwc15hLgdcammBml5tZoZkVrl27thlDlNasaFM5331oEltrann8sjEM6Nkp6pBEUlKrrJg1s/OBAuDuhqa7+4PuXuDuBbm5evBKW7CmpILzH5pEccVWHr10DEN65UQdkkjKSmTlbBGQHzPcLxxXh5kdC9wAHOnulQmKTVqxVZsrOO+hiawuruDRS8cwrG+XqEMSSWmJLDFMBgab2UAzywDOASbEzmBm+wN/BU519zUJjE1aqeUbt3D2Xz9hTXEl4y4erS60RRIgYSUGd682syuBN4A04GF3n2VmtwCF7j6BoOooG/hneE36Unc/NVExSuuyraG5pGIrj146mv13V1IQSYSEXufn7q8Cr9Ybd1PM+2MTGY+0XvPXlHDe34KG5ifGHqTqI5EE0gXg0uoULt7AZeMLSW/XjqcuP5i9equhWSSRWuVVSdJ2vT5zJec9NIluHTN4/geHKCmIREAlBmk1xn20iF+9PJv987vy0IUH0r1TRtQhibRJSgwSueqaWm5/dQ4Pf7SI44b24o/n7E+HDD19TSQqSgwSqY1lVVz55BQ+mr+eiw4ZwC9PGUpaO/WSKhIlJQaJzJxVxYwdX8jqzZXcdeYIzi7I3/FCItLilBgkEhOmreC656aTnZnOU987iFG6R0Gk1VBikIQqr6rhV/+axVOTl3FA/27c/91R9FIPqSKtihKDJMzcVSVc+cQU5q8t5Yqj9uTq44bQPk1XTIu0NkoM0uJqa51HJy7h9le/ICcrnfGXjObwweoVV6S1UmKQFrV0/RZ+9tw0Ji7cwJFDcrn7rBHk5ajqSKQ1U2KQFlFb6zw2aQl3vDaHNDPuPGM4ZxfkE3aOKCKtmBKDNLuZRZu56aWZTFm6iSOG5HLHt4fTp2uHqMMSkSZSYpBms7l8K/e+OZdHJy6hW8cM7jlrJGeM6qtSgkiSUWKQXVZdU8szhcu59625bCir4oKD+vPT4/eiS4f2UYcmIjtBiUF2mrvzxqxV3PX6XBauK6OgfzfGXTxaz04QSXJKDBI3d+eTheu5+425fL50E4Pysvnbfxdw7D55qjYSSQFKDNJk7s67c9fw53fmM2XpJnp1zuTOM4Zzxqh+pOtGNZGUocQgO7S1ppbXZ67igfcWMHtlMX27duDXp+3LWQX5ZLVX99giqUaJQRq1rrSSJyct5fFJS1lVXMEePTtx95kjOH3/vurKQiSFKTFIHe5O4ZKNPDlpKS9PX0lVTS2HD+7JracP4xt75+lZCSJtgBKDALBswxaen1LE858vZ8n6LXTKSOPc0flccPAABuVlRx2eiCSQEkMbtqakgjdnrebl6SuYuHADAAfv0YMfHz2YE4f1plOmvh4ibZH+89uY5Ru38PrMVbwxaxWFSzbiDnv07MQ1xw3hW6P60q9bx6hDFJGIKTGkuIqtNUxatIH3v1zL+1+uZd6aUgD27p3DT44ZwonDejOkV7buPxCRrygxpJiKrTXMKNrMp4s2MHHhej5dtIHK6loy0tsxZmB3zi7I57ihvRjQs1PUoYpIK6XEkOTWllQyo2gTkxdvpHDxBqYt20xVTS0Ag/KyOW/M7hw5JJcxA3vQIUP3HIjIjikxJAl3Z+XmCmatKGZm0ebgtWIzq4srAUhvZwzv14WLDh1AQf9uFAzoTvdOGRFHLSLJSImhlampdZZv3MK81aXMX1vK/DXBa8GaUkoqqwFoZ7BnbjaH7tmTfft2YVifzozo11UlAhFpFkoMCebubCirYtnGcpZt2MKyjVtYtqGc5Ru3sGzDFoo2lbO1xr+aPzcnk8F52XxrVF8G5WWzb58u7LNbDh0z9NGJSMvQ2aWZVFXXsmlLFRu3bGVNSQWriytZU1LBmvDv6uJKVhdXsKakkqrq2jrLdu+UQX63DuzbtwsnDtuNPXp2Ys+8bAblZeuZBiKScAlNDGZ2IvAHIA14yN3vqDc9ExgPHACsB77j7osTEVtNrVNWVU1pRTWlleGropqyympKKoO/m7Zs/erkv3FLFZvCvxvLqiirqmlwvTmZ6eR1ziQvJ4uC/t3I65xF785Z5HfvSH73DvTr1pFs3UgmIq1Iws5IZpYG3AccBywHJpvZBHefHTPbpcBGdx9kZucAdwLfaYl4np68lL/+Z+FXJ/0tjZzY6+uclU63Thl07ZhBj+wMBuVl07Vje7p1zKBbx/Z07ZhBXk4mvTpnkdc5U1U+IpJ0EnnWGg3Md/eFAGb2FHAaEJsYTgNuDt8/C/zZzMzdnWbWvVMm+/btQnZmGtmZ6XTKTCd72ysrGM7Z9j4jGJ+Tla7nDohIyktkYugLLIsZXg6MaWwed682s81AD2Bd7ExmdjlwOcDuu+++U8EcN7QXxw3ttVPLioiksqT8+evuD7p7gbsX5ObmRh2OiEhKSWRiKALyY4b7heManMfM0oEuBI3QIiKSIIlMDJOBwWY20MwygHOACfXmmQBcGL4/E3inJdoXRESkcQlrYwjbDK4E3iC4XPVhd59lZrcAhe4+Afg78KiZzQc2ECQPERFJoIReS+nurwKv1ht3U8z7CuCsRMYkIiJ1JWXjs4iItBwlBhERqUOJQURE6rBkv+jHzNYCS6KOYyf0pN6Ne22A9rltaGv7nKz729/dG7wRLOkTQ7Iys0J3L4g6jkTSPrcNbW2fU3F/VZUkIiJ1KDGIiEgdSgzReTDqACKgfW4b2to+p9z+qo1BRETqUIlBRETqUGIQEZE6lBhaATO7xszczHpGHUtLMrO7zWyOmU03sxfMrGvUMbUUMzvRzOaa2Xwzuy7qeFqameWb2btmNtvMZpnZVVHHlChmlmZmn5vZy1HH0lyUGCJmZvnA8cDSqGNJgLeAYe4+AvgS+EXE8bSImOebnwQMBc41s6HRRtXiqoFr3H0ocBDwwzawz9tcBXwRdRDNSYkher8Dfgak/FUA7v6mu1eHgxMJHtaUir56vrm7VwHbnm+estx9pbtPCd+XEJwo+0YbVcszs37AN4GHoo6lOSkxRMjMTgOK3H1a1LFE4BLgtaiDaCENPd885U+S25jZAGB/YFK0kSTE7wl+2NVGHUhzSujzGNoiM3sb6N3ApBuA6wmqkVLG9vbX3V8K57mBoOrh8UTGJi3PzLKB54CfuHtx1PG0JDM7BVjj7p+Z2VFRx9OclBhamLsf29B4MxsODASmmRkE1SpTzGy0u69KYIjNqrH93cbMLgJOAY5J4ce2NuX55inHzNoTJIXH3f35qONJgEOBU83sZCAL6Gxmj7n7+RHHtct0g1srYWaLgQJ3T8ZeGpvEzE4E7gWOdPe1UcfTUswsnaBx/RiChDAZOM/dZ0UaWAuy4NfNI8AGd/9J1PEkWlhi+B93PyXqWJqD2hgkkf4M5ABvmdlUM/tL1AG1hLCBfdvzzb8AnknlpBA6FLgAODr8bKeGv6QlCanEICIidajEICIidSgxiIhIHUoMIiJShxKDiIjUocQgIiJ1KDGINKOwl9FFZtY9HO4WDg+INjKRplNiEGlG7r4MeAC4Ixx1B/Cguy+OLCiROOk+BpFmFnYN8RnwMDAW2M/dt0YblUjTqa8kkWbm7lvN7FrgdeB4JQVJNqpKEmkZJwErgWFRByISLyUGkWZmZvsBxxE8yexqM9st4pBE4qLEINKMwl5GHyB4HsFS4G7gnmijEomPEoNI8xoLLHX3t8Lh+4F9zOzICGMSiYuuShIRkTpUYhARkTqUGEREpA4lBhERqUOJQURE6lBiEBGROpQYRESkDiUGERGp4/8AHXf6g10vGRUAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(np.arange(-5, 5, 0.01),\n",
    "         sigmoid(np.arange(-5, 5, 0.01)));\n",
    "plt.title(\"Sigmoid function plotted from x=-5 to x=5\")\n",
    "plt.xlabel(\"X\")\n",
    "plt.ylabel(\"$sigmoid(x)$\");\n",
    "# plt.savefig(GRAPHS_IMG_FILEPATH + \"05_sigmoid_function.png\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "def init_weights(input_size: int, \n",
    "                 hidden_size: int) -> Dict[str, ndarray]:\n",
    "    '''\n",
    "    Initialize weights during the forward pass for step-by-step neural network model.\n",
    "    '''\n",
    "    weights: Dict[str, ndarray] = {}\n",
    "    weights['W1'] = np.random.randn(input_size, hidden_size)\n",
    "    weights['B1'] = np.random.randn(1, hidden_size)\n",
    "    weights['W2'] = np.random.randn(hidden_size, 1)\n",
    "    weights['B2'] = np.random.randn(1, 1)\n",
    "    return weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    "def forward_loss(X: ndarray,\n",
    "                 y: ndarray,\n",
    "                 weights: Dict[str, ndarray]\n",
    "                 ) -> Tuple[Dict[str, ndarray], float]:\n",
    "    '''\n",
    "    Compute the forward pass and the loss for the step-by-step \n",
    "    neural network model.     \n",
    "    '''\n",
    "    M1 = np.dot(X, weights['W1'])\n",
    "\n",
    "    N1 = M1 + weights['B1']\n",
    "\n",
    "    O1 = sigmoid(N1)\n",
    "    \n",
    "    M2 = np.dot(O1, weights['W2'])\n",
    "\n",
    "    P = M2 + weights['B2']    \n",
    "\n",
    "    loss = np.mean(np.power(y - P, 2))\n",
    "\n",
    "    forward_info: Dict[str, ndarray] = {}\n",
    "    forward_info['X'] = X\n",
    "    forward_info['M1'] = M1\n",
    "    forward_info['N1'] = N1\n",
    "    forward_info['O1'] = O1\n",
    "    forward_info['M2'] = M2\n",
    "    forward_info['P'] = P\n",
    "    forward_info['y'] = y\n",
    "\n",
    "    return forward_info, loss"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [],
   "source": [
    "def loss_gradients(forward_info: Dict[str, ndarray], \n",
    "                   weights: Dict[str, ndarray]) -> Dict[str, ndarray]:\n",
    "    '''\n",
    "    Compute the partial derivatives of the loss with respect to each of the parameters in the neural network.\n",
    "    '''    \n",
    "    dLdP = -(forward_info['y'] - forward_info['P'])\n",
    "    \n",
    "    dPdM2 = np.ones_like(forward_info['M2'])\n",
    "\n",
    "    dLdM2 = dLdP * dPdM2\n",
    "  \n",
    "    dPdB2 = np.ones_like(weights['B2'])\n",
    "\n",
    "    dLdB2 = (dLdP * dPdB2).sum(axis=0)\n",
    "    \n",
    "    dM2dW2 = np.transpose(forward_info['O1'], (1, 0))\n",
    "    \n",
    "    dLdW2 = np.dot(dM2dW2, dLdP)\n",
    "\n",
    "    dM2dO1 = np.transpose(weights['W2'], (1, 0)) \n",
    "\n",
    "    dLdO1 = np.dot(dLdM2, dM2dO1)\n",
    "    \n",
    "    dO1dN1 = sigmoid(forward_info['N1']) * (1- sigmoid(forward_info['N1']))\n",
    "    \n",
    "    dLdN1 = dLdO1 * dO1dN1\n",
    "    \n",
    "    dN1dB1 = np.ones_like(weights['B1'])\n",
    "    \n",
    "    dN1dM1 = np.ones_like(forward_info['M1'])\n",
    "    \n",
    "    dLdB1 = (dLdN1 * dN1dB1).sum(axis=0)\n",
    "    \n",
    "    dLdM1 = dLdN1 * dN1dM1\n",
    "    \n",
    "    dM1dW1 = np.transpose(forward_info['X'], (1, 0)) \n",
    "\n",
    "    dLdW1 = np.dot(dM1dW1, dLdM1)\n",
    "\n",
    "    loss_gradients: Dict[str, ndarray] = {}\n",
    "    loss_gradients['W2'] = dLdW2\n",
    "    loss_gradients['B2'] = dLdB2.sum(axis=0)\n",
    "    loss_gradients['W1'] = dLdW1\n",
    "    loss_gradients['B1'] = dLdB1.sum(axis=0)\n",
    "    \n",
    "    return loss_gradients"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [],
   "source": [
    "def predict(X: ndarray, \n",
    "            weights: Dict[str, ndarray]) -> ndarray:\n",
    "    '''\n",
    "    Generate predictions from the step-by-step neural network model. \n",
    "    '''\n",
    "    M1 = np.dot(X, weights['W1'])\n",
    "\n",
    "    N1 = M1 + weights['B1']\n",
    "\n",
    "    O1 = sigmoid(N1)\n",
    "\n",
    "    M2 = np.dot(O1, weights['W2'])\n",
    "\n",
    "    P = M2 + weights['B2']    \n",
    "\n",
    "    return P"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [],
   "source": [
    "def train(X_train: ndarray, y_train: ndarray,\n",
    "          X_test: ndarray, y_test: ndarray,\n",
    "          n_iter: int = 1000,\n",
    "          test_every: int = 1000,\n",
    "          learning_rate: float = 0.01,\n",
    "          hidden_size= 13,\n",
    "          batch_size: int = 100,\n",
    "          return_losses: bool = False, \n",
    "          return_weights: bool = False, \n",
    "          return_scores: bool = False,\n",
    "          seed: int = 1) -> None:\n",
    "\n",
    "    if seed:\n",
    "        np.random.seed(seed)\n",
    "\n",
    "    start = 0\n",
    "\n",
    "    # Initialize weights\n",
    "    weights = init_weights(X_train.shape[1], \n",
    "                           hidden_size=hidden_size)\n",
    "\n",
    "    # Permute data\n",
    "    X_train, y_train = permute_data(X_train, y_train)\n",
    "    \n",
    "\n",
    "    losses = []\n",
    "        \n",
    "    val_scores = []\n",
    "\n",
    "    for i in range(n_iter):\n",
    "\n",
    "        # Generate batch\n",
    "        if start >= X_train.shape[0]:\n",
    "            X_train, y_train = permute_data(X_train, y_train)\n",
    "            start = 0\n",
    "        \n",
    "        X_batch, y_batch = generate_batch(X_train, y_train, start, batch_size)\n",
    "        start += batch_size\n",
    "    \n",
    "        # Train net using generated batch\n",
    "        forward_info, loss = forward_loss(X_batch, y_batch, weights)\n",
    "\n",
    "        if return_losses:\n",
    "            losses.append(loss)\n",
    "\n",
    "        loss_grads = loss_gradients(forward_info, weights)\n",
    "        for key in weights.keys():\n",
    "            weights[key] -= learning_rate * loss_grads[key]\n",
    "        \n",
    "        if return_scores:\n",
    "            if i % test_every == 0 and i != 0:\n",
    "                preds = predict(X_test, weights)\n",
    "                val_scores.append(r2_score(preds, y_test))\n",
    "\n",
    "    if return_weights:\n",
    "        return losses, weights, val_scores\n",
    "    \n",
    "    return None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "if TEST_ALL:\n",
    "    num_iter = 10000\n",
    "    test_every = 1000\n",
    "    train_info = train(X_train, y_train, X_test, y_test,\n",
    "                       n_iter=num_iter,\n",
    "                       test_every = test_every,\n",
    "                       learning_rate = 0.001,\n",
    "                       batch_size=23, \n",
    "                       return_losses=False, \n",
    "                       return_weights=True, \n",
    "                       return_scores=False,\n",
    "                       seed=80718)\n",
    "    losses = train_info[0]\n",
    "    weights = train_info[1]\n",
    "    val_scores = train_info[2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "if TEST_ALL:\n",
    "    import matplotlib.pyplot as plt\n",
    "    %matplotlib inline\n",
    "    plt.ylim([-1,1])\n",
    "    plt.plot(list(range(int(num_iter / test_every - 1))), val_scores); \n",
    "    plt.xlabel(\"Batches (000s)\")\n",
    "    plt.title(\"Validation Scores\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Learning rate tuning"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "def r2_score_lr(learning_rate):\n",
    "    train_info = train(X_train, y_train, X_test, y_test,\n",
    "                   n_iter=100000,\n",
    "                   test_every = 100000,\n",
    "                   learning_rate = learning_rate,\n",
    "                   batch_size=23, \n",
    "                   return_losses=False, \n",
    "                   return_weights=True, \n",
    "                   return_scores=False,\n",
    "                   seed=80718)\n",
    "    weights = train_info[1]\n",
    "    preds = predict(X_test, weights)\n",
    "    return r2_score(y_test, preds)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [],
   "source": [
    "if TEST_ALL:\n",
    "    lrs = np.geomspace(1e-2, 1e-6, num=20)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [],
   "source": [
    "if TEST_ALL:\n",
    "    r2s = [r2_score_lr(lr) for lr in lrs]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [],
   "source": [
    "if TEST_ALL:\n",
    "    plt.semilogx(lrs, r2s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Evaluating best model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_info = train(X_train, y_train, X_test, y_test,\n",
    "                   n_iter=10000,\n",
    "                   test_every = 1000,\n",
    "                   learning_rate = 0.001,\n",
    "                   batch_size=23, \n",
    "                   return_losses=True, \n",
    "                   return_weights=True, \n",
    "                   return_scores=False,\n",
    "                   seed=180807)\n",
    "losses = train_info[0]\n",
    "weights = train_info[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(list(range(10000)), losses);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [],
   "source": [
    "preds = predict(X_test, weights)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Investigation of most important features"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Most important combinations of features are the two with absolute values of greater than 9:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[  6.8818],\n",
       "       [  7.3908],\n",
       "       [  5.632 ],\n",
       "       [  7.2358],\n",
       "       [  7.6253],\n",
       "       [  6.754 ],\n",
       "       [  3.3251],\n",
       "       [  9.7287],\n",
       "       [  5.6011],\n",
       "       [-10.2469],\n",
       "       [  5.5645],\n",
       "       [  5.6762],\n",
       "       [ -4.4088]])"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "weights['W2']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "These are at index 7 and index 9. Here are the combinations themselves:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-3.3532e+00, -4.6775e-01,  5.4810e-01, -8.8043e-02,  1.7536e+00,\n",
       "       -5.3111e+00, -9.4313e-01, -5.8730e-01, -1.2341e-03,  1.1375e+00,\n",
       "       -5.2801e-01,  1.1592e+00,  1.6007e+00])"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "weights['W1'][7]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-2.6785,  3.9213,  2.2398, -3.6323, -0.2241,  3.1889,  0.3231,\n",
       "        0.4316, -1.9733,  0.2403, -1.4463, -0.5084,  1.5561])"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "weights['W1'][9]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Mean absolute error: 2.5951 \n",
      "Root mean squared error: 3.8851\n"
     ]
    }
   ],
   "source": [
    "print(\"Mean absolute error:\", round(mae(preds, y_test), 4), \"\\n\"\n",
    "      \"Root mean squared error:\", round(rmse(preds, y_test), 4))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.xlabel(\"Predicted value\")\n",
    "plt.ylabel(\"Target\")\n",
    "plt.title(\"Predicted value vs. target,\\n neural network regression\")\n",
    "plt.xlim([0, 51])\n",
    "plt.ylim([0, 51])\n",
    "plt.scatter(preds, y_test)\n",
    "plt.plot([0, 51], [0, 51]);\n",
    "# plt.savefig(GRAPHS_IMG_FILEPATH + \"07_neural_network_regression_preds_vs_target.png\");"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.5951"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.round(np.mean(np.array(np.abs(preds - y_test))), 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "15.0943"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.round(np.mean(np.array(np.power(preds - y_test, 2))), 4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Theoretical relationship between most important feature and target"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [],
   "source": [
    "NUM = 40\n",
    "a = np.repeat(X_test[:,:-1].mean(axis=0, keepdims=True), NUM, axis=0)\n",
    "b = np.linspace(-1.5, 3.5, NUM).reshape(NUM, 1)\n",
    "test_feature = np.concatenate([a, b], axis=1)\n",
    "preds_test = predict(test_feature, weights)[:, 0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X_test[:, 12], preds)\n",
    "plt.plot(np.array(test_feature[:, -1]), preds_test, linewidth=2, c='orange')\n",
    "plt.ylim([6, 51])\n",
    "plt.xlabel(\"Most important feature (normalized)\")\n",
    "plt.ylabel(\"Target/Predictions\")\n",
    "plt.title(\"Most important feature vs. target and predictions,\\n neural network regression\");\n",
    "# plt.savefig(GRAPHS_IMG_FILEPATH + \"08_neural_network_regression_impt_feat_vs_preds.png\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
